#include "data_flood.h"
#include "libpq-fe.h"

extern void executeCommand(const char* sql);
extern PGresult* executeQuery(const char* sql, bool permit_error);
extern void analyse_query_result(PGresult* result);


void test_func(void)
{
    char* table_name = "opengauss_table_303_t1";
    char* query_sql = "SELECT * FROM opengauss_table_303_t1";
    PGresult* res = NULL;


    doConnect(NULL);
    res = executeQuery(query_sql, false);
    analyse_query_result(res);
    PQclear(res);
}

uint32 get_table_relfilenode(char* relname)
{
    char sql_buf[1024] = {0};
    PGresult* res = NULL;
    char* value = NULL;
    uint32 result = 0;

    sprintf(sql_buf, "select pg_relation_filenode('%s');", relname);
    res = executeQuery(sql_buf, false);

    value = PQgetvalue(res, 0, 0);
    result = str_to_uint32(value);
    PQclear(res);

    return result;
}

char* get_table_relpath(char* relname)
{
    char sql_buf[1024] = {0};
    PGresult* res = NULL;
    char* value = NULL;
    char* result = NULL;

    sprintf(sql_buf, "select pg_relation_filepath('%s');", relname);
    res = executeQuery(sql_buf, false);

    value = PQgetvalue(res, 0, 0);
    result = strdup(value);
    PQclear(res);

    return result;
}

char* get_data_dir(void)
{
    char sql_buf[1024] = {0};
    PGresult* res = NULL;
    char* value = NULL;
    char* result = NULL;

    sprintf(sql_buf, "show data_directory");
    res = executeQuery(sql_buf, false);

    value = PQgetvalue(res, 0, 0);
    result = strdup(value);
    PQclear(res);

    return result;
}

uint32 get_table_pages(char* relname)
{
    char sql_buf[1024] = {0};
    PGresult* res = NULL;
    char* value = NULL;
    uint32 result = 0;

    sprintf(sql_buf, "select pg_relation_size('%s') / 8192;", relname);
    res = executeQuery(sql_buf, false);

    value = PQgetvalue(res, 0, 0);
    result = str_to_uint32(value);
    PQclear(res);

    return result;
}

uint32 get_table_reloid(char* relname)
{
    char sql_buf[1024] = {0};
    PGresult* res = NULL;
    char* value = NULL;
    uint32 result = 0;

    sprintf(sql_buf, "SELECT oid FROM pg_class WHERE relname = '%s'", relname);
    res = executeQuery(sql_buf, false);

    value = PQgetvalue(res, 0, 0);
    result = str_to_uint32(value);
    PQclear(res);

    return result;
}

AttributeMap* get_table_attmap(char* relname)
{
    AttributeMap *result = NULL;
    PGresult* res = NULL;
    char sql_buf[1024] = {0};
    uint32 reloid = 0;
    uint32 atts = 0;
    char* value = NULL;

    uint32 atttypid = 0;
    char* attname = NULL;
    char* atttypname = NULL;

    reloid = get_table_reloid(relname);
    sprintf(sql_buf, "SELECT atttypid,typname,attname, atttypmod FROM pg_attribute JOIN pg_type ON atttypid=pg_type.oid WHERE attrelid = %u AND attnum > 0 AND attisdropped=false ORDER BY attnum;", reloid);

    res = executeQuery(sql_buf, false);
    atts = PQntuples(res);
    if(atts <= 0)
        df_error("Wrong atts %d", atts);

    result = (AttributeMap*)df_malloc(atts * sizeof(AttributeMap));
    for(int loop = 0; loop < atts; loop++) {
        value = PQgetvalue(res, loop, 0);
        result[loop].typid = str_to_uint32(value);
        value = PQgetvalue(res, loop, 1);
        memcpy(result[loop].typname, value, strlen(value));
        value = PQgetvalue(res, loop, 2);
        memcpy(result[loop].attname, value, strlen(value));
        value = PQgetvalue(res, loop, 3);
        result[loop].atttypmod = str_to_int32(value);
        result[loop].atts = atts;
    }
    PQclear(res);
    return result;
}

void get_database_type(void)
{
    PGresult* res = NULL;
    char* sql_buf = "select version()";
    char* version_str = NULL;

    res = executeQuery(sql_buf, false);
    version_str = PQgetvalue(res, 0, 0);
    if(strstr(version_str, "openGauss"))
        user_arg.db_type = DBTYPE_OPENGAUSS;
    else if(strstr(version_str, "PostgreSQL"))
        user_arg.db_type = DBTYPE_POSTGRES;
    else {
        PQclear(res);
        df_error("Unsupport database version %s", version_str);
    }

    PQclear(res);
}

void lock_table(char* relname)
{
    char sql_buf[1024] = {0};

    sprintf(sql_buf, "LOCK TABLE %s IN SHARE MODE", relname);
    executeCommand("BEGIN");
    executeCommand(sql_buf);
}

void truncate_table(char* relname)
{
    char sql_buf[1024] = {0};

    sprintf(sql_buf, "TRUNCATE %s", relname);
    executeCommand(sql_buf);
}

void release_table(void)
{
    executeCommand("COMMIT");
}

void exec_checkpoint(void)
{
    executeCommand("CHECKPOINT");
}

void base_data_import(char *sql)
{
    executeCommand(sql);
    exec_checkpoint();
}
